package p.ithorns.example.statemachine.core;

import lombok.extern.slf4j.Slf4j;
import p.ithorns.framework.core.exception.BizException;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

/**
 * StateMachine
 * 状态机
 *
 * @author ithorns
 * @version 1.0.0
 * @date 2022/11/13 11:46
 */
@Slf4j
public abstract class StateMachine {

    /**
     * 状态集
     */
    private final Map<StateEnum, State> states;

    public StateMachine() {
        this.states = declareStates();
    }


    /**
     * 状态转换
     * 1.获取状态
     * 2.由具体转换机执行转换
     *
     * @param stateCode -状态码
     * @param event     -事件
     * @return 下个状态
     */
    public State transition(final StateEnum stateCode, final Event event) {
        State state = getState(stateCode);
        List<Action> actions = state.getActions();
        for (Action action : actions) {
            if (event.getType() == action.getEventType()) {
                log.info("当前的状态: {}", state);
                State nextState = action.execute(event);
                log.info("[{}]执行后的状态: {}", action.getClass().getSimpleName(), nextState);
                return nextState;
            }
        }
        throw new BizException(MessageFormat.format("当前状态({0})不支持该事件({1})", state, event));
    }

    /**
     * 定义状态集
     *
     * @return Map<FlowStateEnum, State>
     */
    public abstract Map<StateEnum, State> declareStates();

    private State getState(StateEnum stateCode) {
        return states.get(stateCode);
    }

}